package proxy.dynamic.proxy;

import proxy.dynamic.util.Logger;
import sun.rmi.runtime.Log;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

/**
 * 动态代理: 可以代理多类类型对象
 * 实质：    在运行期间通过代码生成一个实现与目标类同一个接口的类
 * 局限：   只能代理实现了接口的类
 */
public class BeanDynamicProxy {
    // 持有目标类型句柄
    private Object target;


    /**
     * 根据目标类实现的接口生成对应代理类的实例
     * @param target
     * @return
     */
    public Object getBeanProxy(Object target) {
        this.target = target;

        /**
         * classLoader: 目标类的类加载器
         * interfaces:  目标类实现的接口组成数组
         * invocationHandler: 实现InvocationHandler接口的实现类实例
         */
        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new MyHandler()
        );


    }

    /**
     * 通过代理对象调用目标类方法的回调类
     */
    private class MyHandler implements InvocationHandler {

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//            System.out.println(proxy.getClass());
//            System.out.println(method.getName());
//            if (args != null) {
//                System.out.println(Arrays.asList(args));
//            }
            Logger.info("执行了"+method.getName()+"方法之前");
            Object result = method.invoke(target, args);
            Logger.info("执行了"+method.getName()+"方法之后");

            return result;
        }
    }
}
